import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { CommentConstants } from 'src/constants/comment';
import { ContentStatus } from 'src/constants/constants';
import { IsNull, Repository } from 'typeorm';
import { CreateCommentDto } from './dto/create.comment.dto';
import { CommentEntity } from './entities/comment.entity';
import { CommentLikeEntity } from './entities/comment.like.entity';

@Injectable()
export class CommentService {
  constructor(
    @InjectRepository(CommentEntity)
    private readonly commentRepository: Repository<CommentEntity>,
    @InjectRepository(CommentLikeEntity)
    private readonly commentLikeRepository: Repository<CommentLikeEntity>,
  ) {}

  /**
   * 是否是有效的评论源
   */
  isValidSource(source: string) {
    if ([CommentConstants.SourceArticle, CommentConstants.SourceMessage].indexOf(source) >= 0) {
      return true;
    }
    return false;
  }

  /**
   * 创建评论
   */
  async create(source: string, createCommentDto: CreateCommentDto, userId: string) {
    const commentRepository = this.getCommentSchema(source);
    // articleId 文章的时候是文章id
    // parentId 表示父级评论id
    // rootId 表示一级评论  不填为一级

    const comment = this.getCommentEntity(source);
    if (createCommentDto.rootId) {
      comment.rootId = createCommentDto.rootId;
    }
    if (createCommentDto.parentId) {
      comment.parentId = createCommentDto.parentId;
    }
    if (createCommentDto.articleId && comment instanceof CommentEntity) {
      comment.articleId = createCommentDto.articleId;
    }

    comment.status = ContentStatus.VerifySuccess;
    comment.userId = userId;
    comment.content = createCommentDto.content;

    return commentRepository.save(comment);
  }

  /**
   * @Author: laotongshu
   * @Date: 2022-10-08 16:53:10
   * @LastEditors: laotongshu
   * @Description: 获取一级评论
   * @param {Object} {}
   * @return {*}
   */
  async getCommentList(source: string, articleId: string) {
    // 判断是不是留言，或者文章评论的，不是报错
    if (!this.isValidSource(source)) {
      return '报错';
    }
    const commentRepository = this.getCommentSchema(source);
    const query: any = {
      rootId: IsNull(),
      status: ContentStatus.VerifySuccess,
    };
    if (
      articleId &&
      articleId !== CommentConstants.CommonMessageID &&
      source === CommentConstants.SourceArticle
    ) {
      query.articleId = articleId;
    }
    const list = await commentRepository.find({
      where: query,
      relations: ['user'],
    });

    const counts_p = list.map(async (item) => {
      return await commentRepository.countBy({
        status: ContentStatus.VerifySuccess,
        rootId: item.id,
      });
    });
    const counts = await Promise.all(counts_p);
    const comments = list.map((item, index) => {
      return {
        ...item,
        commentCounts: counts[index],
      };
    });

    return comments;
  }

  /**
   * @Author: laotongshu
   * @Date: 2022-10-08 17:25:42
   * @LastEditors: laotongshu
   * @Description: 获取二级评论
   * @param {Object} {}
   * @return {*}
   */
  async getChildCommentList(source: string, rootId: string) {
    // 判断是不是留言，或者文章评论的，不是报错
    if (!this.isValidSource(source)) {
      return '报错';
    }
    const commentRepository = this.getCommentSchema(source);
    return commentRepository.find({
      where: {
        rootId,
        status: ContentStatus.VerifySuccess,
      },
      relations: ['parent', 'parent.user', 'user'],
    });
  }

  /**
   * @Author: laotongshu
   * @Date: 2022-10-08 18:08:18
   * @LastEditors: laotongshu
   * @Description: 点赞
   * @param source: 来源
   * @param cid: 评论的id
   * @param uid: 用户的id
   * @return {*}
   */
  async clickLike(source, cid, user) {
    if (!this.isValidSource(source)) {
      return '报错';
    }
    const hasLike = await this.hashLikeByUid(source, cid, user.id);
    let result;
    if (hasLike) {
      // 取消点赞
      result = await this.unlikeById(source, cid, user.id);
    } else {
      result = await this.likeById(source, cid, user.id);
    }
    return result;
  }
  /**
   * @Author: laotongshu
   * @Date: 2022-10-08 18:06:17
   * @LastEditors: laotongshu
   * @Description: 添加点赞
   * @param source: 来源
   * @param cid: 评论的id
   * @param uid: 用户的id
   * @return {*}
   */
  async likeById(source, cid, uid) {
    const commentRepository = this.getCommentSchema(source);
    const data = await commentRepository.findOneOrFail({
      where: { id: cid },
      relations: ['likes'],
    });
    const like = this.getCommentLikeEntity(source);
    like.userId = uid; // 用户id
    like.commentId = cid; // 评论的id
    data.likes = [...data.likes, like] as any[];
    await commentRepository.save(data);
    return like;
  }

  /**
   * @Author: laotongshu
   * @Date: 2022-10-08 18:07:12
   * @LastEditors: laotongshu
   * @Description: 取消点赞
   * @param source: 来源
   * @param cid: 评论的id
   * @param uid: 用户的id
   * @return {*}
   */
  async unlikeById(source, cid, uid) {
    const commentRepository = this.getCommentLikeSchema(source);
    return commentRepository.delete({
      userId: uid,
      commentId: cid,
    });
  }

  /**
   * @Author: laotongshu
   * @Date: 2022-10-08 17:50:03
   * @LastEditors: laotongshu
   * @Description: 判断该用户是否已经点赞
   * @param source: 来源
   * @param cid: 评论的id
   * @param uid: 用户的id
   * @return {*}
   */
  async hashLikeByUid(source, cid, uid) {
    const commentRepository = this.getCommentSchema(source);
    const sourceObj = await commentRepository.findOneOrFail({
      where: { id: cid },
      relations: ['likes'],
    });
    if (sourceObj?.likes?.length) {
      return (sourceObj.likes as CommentLikeEntity[]).find((item) => {
        return uid === item.userId;
      });
    }
    return false;
  }

  // 调用文章评论还是留言
  private getCommentSchema(source: string) {
    let commentRepository: Repository<CommentEntity>;
    if (source === CommentConstants.SourceArticle) {
      commentRepository = this.commentRepository;
    }
    return commentRepository;
  }

  // 使用entitry的是文章评论还是留言
  private getCommentEntity(source: string) {
    let entity: CommentEntity;
    if (source === CommentConstants.SourceArticle) {
      entity = new CommentEntity();
    }
    return entity;
  }

  // 点赞调用文章评论还是留言
  private getCommentLikeSchema(source: string) {
    let commentRepository: Repository<CommentLikeEntity>;
    if (source === CommentConstants.SourceArticle) {
      commentRepository = this.commentLikeRepository;
    }
    return commentRepository;
  }

  // 点赞使用entitry的是文章评论还是留言
  private getCommentLikeEntity(source: string) {
    let entity: CommentLikeEntity;
    if (source === CommentConstants.SourceArticle) {
      entity = new CommentLikeEntity();
    }
    return entity;
  }
}
